package com.yuejiekeji.photowall.util;

import cn.hutool.core.util.StrUtil;
import com.yuejiekeji.photowall.common.BizException;
import com.yuejiekeji.photowall.common.Const;
import com.yuejiekeji.photowall.common.SpringContextHolder;
import com.yuejiekeji.photowall.entity.User;
import com.yuejiekeji.photowall.enums.EResponseCode;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;


import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.*;

@Slf4j
public class JWTUtil {

    public static Long ONE_DAY = 86400000L;
    public static String SECRET = "94ca33kc5vviycrq896reg5owrkd5gypb1vlu5tdthsje1wd2g6p4u57lvyrc1mqgwq3wd3y7pmm27vxhaybi0ify0ko9syy4zi39pv3h536ckkmyx0vjnuygff8571u";
    public static SecretKey key;

    static {
        key = Jwts.SIG.HS256.key().random(new SecureRandom(SECRET.getBytes(StandardCharsets.UTF_8))).build();
    }


    public static String getToken(User user){
        long currTime = System.currentTimeMillis();

        Map<String, Object> claims = new HashMap<>();
        claims.put("id",user.getId());
        claims.put("loginName",user.getUsername());

        JwtBuilder jwtBuilder = Jwts.builder().id(UUID.randomUUID().toString()).issuer("yuejie").claims(claims)
                .expiration(new Date(currTime + ONE_DAY)).issuedAt(new Date(currTime))
                .signWith(key);

        jwtBuilder.header().add("alg","HS256");
        jwtBuilder.header().add("typ","JWT");
        jwtBuilder.header().add("domain","yuejiekeji.com");

        return jwtBuilder.compact();

    }

    public static Integer getUid(String token){

        try {
            Claims claims = Jwts.parser().verifyWith(key).build().parseSignedClaims(token).getPayload();

            Integer uid = (Integer) claims.get("id");
            RedisTemplate redisTemplate = SpringContextHolder.getBean("redisTemplate");

            String key = Const.RedisKeyPrefix.LOGIN_USER + uid;

            String oldToken = (String) redisTemplate.opsForValue().get(key);

            if (StrUtil.isBlank(oldToken) || !Objects.equals(oldToken,token)){
                throw new BizException(EResponseCode.TOKEN_ERROR.getCode());
            }
            return (Integer) claims.get("id");
        }catch (Exception e){
            throw new BizException(EResponseCode.TOKEN_ERROR.getCode());
        }



    }

}
